namespace WP7Contrib.Services.BingMaps.Model
{
    using System;
    using System.Device.Location;
    using Common;

    public class SearchData : BaseModel, ICloneable<SearchData>
    {
        private string address;
        private string business;
        private Uri businessUrl;
        private string city;
        private string countryOrRegion;
        private Uri displayUrl;
        private GeoCoordinate location;
        private string phoneNumber;
        private string postalCode;
        private int reviewCount;
        private string title;
        private string uniqueId;
        private double userRating;
        private Uri url;

        public string Address
        {
            get
            {
                return this.address;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.address, value, () => this.Address);
            }
        }

        public string Business
        {
            get
            {
                return this.business;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.business, value, () => this.Business);
            }
        }

        public Uri BusinessUrl
        {
            get
            {
                return this.businessUrl;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.businessUrl, value, () => this.BusinessUrl);
            }
        }

        public string City
        {
            get
            {
                return this.city;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.city, value, () => this.City);
            }
        }

        public string CountryOrRegion
        {
            get
            {
                return this.countryOrRegion;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.countryOrRegion, value, () => this.CountryOrRegion);
            }
        }

        public Uri DisplayUrl
        {
            get
            {
                return this.displayUrl;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.displayUrl, value, () => this.DisplayUrl);
            }
        }

        public GeoCoordinate Location
        {
            get
            {
                return this.location;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.location, value, () => this.Location);
            }
        }

        public string PhoneNumber
        {
            get
            {
                return this.phoneNumber;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.phoneNumber, value, () => this.PhoneNumber);
            }
        }

        public string PostalCode
        {
            get
            {
                return this.postalCode;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.postalCode, value, () => this.PostalCode);
            }
        }

        public int ReviewCount
        {
            get
            {
                return this.reviewCount;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.reviewCount, value, () => this.ReviewCount);
            }
        }

        public string Title
        {
            get
            {
                return this.title;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.title, value, () => this.Title);
            }
        }

        public string UniqueId
        {
            get
            {
                return this.uniqueId;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.uniqueId, value, () => this.UniqueId);
            }
        }

        public Uri Url
        {
            get
            {
                return this.url;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.url, value, () => this.Url);
            }
        }

        public double UserRating
        {
            get
            {
                return this.userRating;
            }
            set
            {
                this.SetPropertyAndNotify(ref this.userRating, value, () => this.UserRating);
            }
        }

        public bool HasLocation
        {
            get { return this.location != null; }
        }

        public bool HasBusinessUrl
        {
            get { return this.businessUrl != null; }
        }

        public bool HasDisplayUrl
        {
            get { return this.displayUrl != null; }
        }

        public bool HasUrl
        {
            get { return this.url != null; }
        }

        public SearchData ShallowClone()
        {
            var data = new SearchData
            {
                Address = this.address,
                Business = this.business,
                BusinessUrl = this.businessUrl,
                City = this.city,
                CountryOrRegion = this.countryOrRegion,
                DisplayUrl = this.displayUrl,
                Location = this.location,
                PhoneNumber = this.phoneNumber,
                PostalCode = this.postalCode,
                ReviewCount = this.reviewCount,
                Title = this.title,
                UniqueId = this.uniqueId,
                UserRating = this.userRating,
                Url = this.url
            };

            return data;
        }

        public SearchData DeepClone()
        {
            var data = new SearchData
            {
                Address = this.address,
                Business = this.business,
                City = this.city,
                CountryOrRegion = this.countryOrRegion,
                PhoneNumber = this.phoneNumber,
                PostalCode = this.postalCode,
                ReviewCount = this.reviewCount,
                Title = this.title,
                UniqueId = this.uniqueId,
                UserRating = this.userRating,
            };

            if (this.HasLocation)
                data.Location = new GeoCoordinate(this.location.Latitude, this.location.Longitude);

            if (this.HasBusinessUrl)
                data.BusinessUrl = new Uri(this.businessUrl.ToString());

            if (this.HasDisplayUrl)
                data.DisplayUrl = new Uri(this.displayUrl.ToString());

            if (this.HasUrl)
                data.Url = new Uri(this.url.ToString());

            return data;
        }
    }
}